package com.ruoyi.common.s7.ST30B;

import com.github.s7connector.api.DaveArea;
import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.github.s7connector.impl.serializer.converter.*;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

/**
 * @author guoxl
 * @Form no
 * @Description ToDo
 * @createTime 2021/1/26 17:09
 **/
@Slf4j
public class ST30BHandle {

    //Int类型的封装类 用来转义
    private static IntegerConverter intCon = new IntegerConverter();

    private static ByteConverter byteCon = new ByteConverter();
    //String...
    private static StringConverter strCon = new StringConverter();
    //Boolean...
    private static BitConverter boolCon = new BitConverter();
    //real实数浮点...
    private static RealConverter realCon = new RealConverter();


    /**
     * 读取数据
     * @param connector
     * @param areaNumber
     * @return
     */
    public ST30BVo read(S7Connector connector, int areaNumber) {
        ST30BVo st30BVo = new ST30BVo();
        byte[] PlcData = null;

        //partNr
        PlcData = connector.read(DaveArea.DB, areaNumber, 40, 92);
        st30BVo.setPartNr(strCon.extract(new String().getClass(), PlcData, 0, 0));
        //newPnFlag
        PlcData = connector.read(DaveArea.DB,areaNumber, 1, 134);
        st30BVo.setNewPnFlag(byteCon.extract(Byte.class, PlcData, 0, 0));
        //totalFlowResult
        PlcData = connector.read(DaveArea.DB,areaNumber, 1, 134);
        st30BVo.setTotalFlowResult(byteCon.extract(Byte.class, PlcData, 0, 0));
        //newTotalFlowResultFlag
        PlcData = connector.read(DaveArea.DB,areaNumber, 1, 134);
        st30BVo.setNewTotalFlowResultFlag(byteCon.extract(Byte.class, PlcData, 0, 0));

        return st30BVo;
    }

    public static S7Connector initConnect(String ipAddress) {
        //默认端口
//      创建与PLC的链接
        S7Connector connector = S7ConnectorFactory.buildTCPConnector()
                .withHost(ipAddress)
                .withRack(0) // 架机号 可选，建议选择，可能会报错
                .withSlot(1) // 插槽号 可选，建议选择，可能会报错
                .build();
        return connector;
    }
    /**
     * 获取对应类型的byte[]数组
     * type:
     *  1-int
     *  2-Dint
     *  3-LReal
     *  4-Real
     */
    public static byte[] getByte(int value1,double value2,int type){
        byte[] bytes = new byte[0];
        if ( type == 1 ){
            bytes = ByteBuffer.allocate(2).putShort((short)value1).array();
        }
        if ( type == 2 ){
            bytes = ByteBuffer.allocate(4).putInt(value1).array();
        }
        if ( type == 3 ){
            bytes = ByteBuffer.allocate(4).putFloat((float) value2).array();
        }
        if ( type == 4 ){
            bytes = ByteBuffer.allocate(8).putDouble(value2).array();
        }
        return bytes;
    }

    /**
     * 写入值
     * dbNum--DB编码，offset--偏移量，value--写入的值,length--写入值占用的字节长度
     * type：
     *  int(java--Integer类型):1
     *  Dint(java--Long类型):2
     *  Real(java--Double):3
     *  LReal(java--长浮点数，没有对应的类型):4
     */
    public static void writeValue(S7Connector s7Connector, int dbNum,int offset,int value,int type){
        //将参数转换成对应格式的byte数组
        byte[] bytes = getByte(value,0,type);
        //写入PLC
        //第一个参数：DaveArea.DB 表示读取PLC的地址区域为DB
        //第二个参数：DB块地址，若plc中是DB1000，则填1000
        //第三个参数：偏移量
        //第四个参数：写入的数据 二进制数组byte[]
        s7Connector.write(DaveArea.DB,dbNum, offset,bytes);
        log.info("写入参数成功，offset--{}，value--{}",offset,value);
    }
}
